package com.ruoyi.app.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;

@Slf4j
public class SignUtil {
	
	//定义加密方式
    public static final String KEY_RSA = "RSA";
	
	//定义签名算法
    private final static String KEY_RSA_SIGNATURE = "SHA256withRSA";

	//获取签名私钥
    public static PrivateKey getMerchantPrivatekey(String partnerPrivateKey) {
        try {
            byte[] keyBytes = Base64.decodeBase64(partnerPrivateKey);
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance(KEY_RSA);
            PrivateKey privateKey = kf.generatePrivate(spec);
            return privateKey;
        } catch (Exception e) {
            log.error("getMerchantPrivatekey fail: ", e);
            return null;
        }
    }
    
    //通过私钥签名
    public static byte[] signAture(byte[] signedContentStr,PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
        signature.initSign(privateKey);
        signature.update(signedContentStr);
        return signature.sign();
    }

	//获取验签公钥
    public static PublicKey getMerchantPublicKey(String partnerPublicKey) {
        try {
            byte[] keyBytes = Base64.decodeBase64(partnerPublicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance(KEY_RSA);
            PublicKey publicKey = kf.generatePublic(keySpec);
            return publicKey;
        } catch (Exception e) {
            log.error("getMerchantPublicKey fail: ", e);
            return null;
        }
    }
    
	//通过公钥验签
    public static boolean signVerify(byte[] signedContentStr,PublicKey publicKey, byte[] sign) throws Exception {
    	boolean flag = false;
        Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
        signature.initVerify(publicKey);
        signature.update(signedContentStr);
        flag = signature.verify(sign);
        return flag;
    }
    
    //签名规则
    public static String MaptoString(Map<String,String> params){
        Set<String> keySet = params.keySet();
        String[] keysArr = keySet.toArray(new String[0]);
        Arrays.sort(keysArr);
        StringBuilder signedContent = new StringBuilder();
        for(int i = 0; i < keysArr.length; i++) {
            signedContent.append(keysArr[i]).append("=").append(params.get(keysArr[i])).append("&");
        }
        String signedContentStr = signedContent.toString();
        if(signedContentStr.endsWith("&"))
            signedContentStr = signedContentStr.substring(0, signedContentStr.length() - 1);
        return signedContentStr;
    }
}
